[AWS CDK] NodejsFunctionで共通で行いたい設定(bundling.forceDockerBundlingなど)をカスタムConstructクラスで省略する
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、NodejsFunctionクラスで共通で行いたい設定(bundling.forceDockerBundlingなど)を、カスタムConstructクラスを作って省略してみました。
NodejsFunctionのローカルビルドに必要な対応
MacOS上でNodejsFunctionクラスのConstructを含むAWS CDK Stackをローカルビルドする際には、次のいずれかの対応が必要です。
- Docker Desktopが起動していること
esbuild
がインスールされており、NodejsFunction
のbundling.forceDockerBundling
propがfalse
に設定されていること
上記対応がなされていない場合、CDKビルドがエラーとなります。
$ cdk synth Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? ERRO[0000] Can't add file /Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws_cdk_app/node_modules/aws-cdk-lib/aws-lambda-nodejs/lib/bundling.js.map to tar: io: read/write on closed pipe ERRO[0000] Can't close tar writer: io: read/write on closed pipe
関数ごとにbundling.forceDockerBundling設定するのは冗長
前述の2.方法で対応する前提とした場合、作成する全てまたはほとんどのLambda関数に共通でbundling.forceDockerBundling
を設定する必要があるのですが、関数の数が増えてくると冗長になってきます。
//(省略なし) import { Construct } from 'constructs'; import { Stack, StackProps, aws_lambda_nodejs } from 'aws-cdk-lib'; export class AwsCdkAppStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new aws_lambda_nodejs.NodejsFunction(this, 'HelloWorld1', { entry: 'src/lambda/handlers/hello-world-handler.ts', bundling: { forceDockerBundling: false, }, }); new aws_lambda_nodejs.NodejsFunction(this, 'HelloWorld2', { entry: 'src/lambda/handlers/hello-world-handler.ts', bundling: { forceDockerBundling: false, }, }); new aws_lambda_nodejs.NodejsFunction(this, 'HelloWorld3', { entry: 'src/lambda/handlers/hello-world-handler.ts', bundling: { forceDockerBundling: false, }, }); new aws_lambda_nodejs.NodejsFunction(this, 'HelloWorld4', { entry: 'src/lambda/handlers/hello-world-handler.ts', bundling: { forceDockerBundling: false, }, }); new aws_lambda_nodejs.NodejsFunction(this, 'HelloWorld5', { entry: 'src/lambda/handlers/hello-world-handler.ts', bundling: { forceDockerBundling: false, }, }); //and more... } }
カスタムConstructクラスで省略してみる
そこでbundling.forceDockerBundling
の設定を、カスタムConstructクラスを使用して省略してみます。
まずカスタムConstructクラスを別ファイルで作成します。NodejsFunction
のbundling.forceDockerBundling
が既定でfalse
となるようにし、またentry
は格納パスがsrc/lambda/handlers/
で固定であると想定し、ファイル名のみを指定すれば良いようにしています。
//カスタムConstructクラス import { Construct } from 'constructs'; import { aws_lambda_nodejs } from 'aws-cdk-lib'; export interface AwsCdkNodejsLambdaHandlerProps { handlerFile: string; } export class AwsCdkNodejsLambdaHandler extends Construct { public readonly queueArn: string; constructor( scope: Construct, id: string, props: AwsCdkNodejsLambdaHandlerProps ) { super(scope, id); new aws_lambda_nodejs.NodejsFunction(this, 'AwsCdkNodejsLambdaHandler', { entry: `src/lambda/handlers/${props.handlerFile}.ts`, bundling: { forceDockerBundling: false, }, }); } }
作成したカスタムConstructクラスを使用してLambda関数を定義します。
//(省略あり) import { Construct } from 'constructs'; import { Stack, StackProps } from 'aws-cdk-lib'; import { AwsCdkNodejsLambdaHandler } from './custom-construct-class'; export class AwsCdkAppStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new AwsCdkNodejsLambdaHandler(this, 'HelloWorld1', { handlerFile: 'hello-world-handler', }); new AwsCdkNodejsLambdaHandler(this, 'HelloWorld2', { handlerFile: 'hello-world-handler', }); new AwsCdkNodejsLambdaHandler(this, 'HelloWorld3', { handlerFile: 'hello-world-handler', }); new AwsCdkNodejsLambdaHandler(this, 'HelloWorld4', { handlerFile: 'hello-world-handler', }); new AwsCdkNodejsLambdaHandler(this, 'HelloWorld5', { handlerFile: 'hello-world-handler', }); //and more... } }
ビルドを行うとエラー無く実行されました。
$ cdk synth Bundling asset AwsCdkAppStack/HelloWorld1/AwsCdkNodejsLambdaHandler/Code/Stage... cdk.out/bundling-temp-e3d6ffa14aa789fb0ae3789c57f95d9554e8d404e91655d711e4df0617e9c42c/index.js 188b ⚡ Done in 3ms Resources: HelloWorld1AwsCdkNodejsLambdaHandlerServiceRoleDBC2ED23: ...
おわりに
NodejsFunctionで共通で行いたい設定(bundling.forceDockerBundlingなど)をカスタムConstructクラスで省略してみました。
そもそも今までbundling.forceDockerBundling
の設定を知らず、NodejsFunction
を作成する開発の際にはデスクトップで必ずDockerを起動するようにしていたのですが、今後はしなくて良くなりました。
参考
- AWS CDK でカスタム Construct を作って、他の CDK プロジェクトから使ってみる | DevelopersIO
- [AWS-CDK] NodejsFunction の snapshot test がCI環境で落ちる
- aws-cdk-lib.aws_lambda_nodejs module · AWS CDK
以上